require 'src/main/ruby/main/init'
require 'pathname'
require 'singleton'
java_import(de.recipeminer.environments.ExecutionContextProvider)

module Configuration
  class << self
    def project_home_path
      Init::project_home_path
    end
    alias_method :project_path, :project_home_path

    def maven_resource(rel_path)
      ret = get_resource_finder.get_resource_file(rel_path).absolute_path
    end
    alias_method :resource, :maven_resource

    def maven_resource_path(respect_env = true)
      mavenProps = get_resource_finder.maven_properties
      javaDir = mavenProps[(get_env.eql? 'test') ? 'maven.testSourceDir' : 'maven.sourceDir']
      path_elems = [Pathname(javaDir).parent, 'resources']
      path_elems << get_env if respect_env
      File.join(path_elems)
    end
    alias_method :resource_path, :maven_resource_path

    def get_resource_finder
      ExecutionContextProvider.current_resource_finder
    end
    private :get_resource_finder

    def get_env
      @env ||= ENV['MINERENV'] || 'development'
    end
  end
    
  class ConfigContainer
    include Singleton
    def initialize
      @config_cache = Hash.new
    end

    def get(category)
      conf =  @config_cache[category.to_sym]
      conf ||= get_yaml_config(category)
      if conf.nil? || (! conf.respond_to? :'[]')
        raise "Unable to retrieve config hash for category: #{category} " +
          "(#{category.class}"
      end
      conf
    end

    alias_method :'[]', :get
    
    private
    def get_yaml_config(category)
      begin
        filename = category.to_s.gsub(/\P{ASCII}|\p{Space}/, '_')
        rel_path = File.join("#{filename}.yaml")
        path = ExecutionContextProvider.current_config_finder.get_file(rel_path).get_canonical_path
        puts "Looking up config in #{path}"
        yaml_content = YAML.load_file(path)
        @config_cache[category.to_sym] = yaml_content[category.to_sym]
      rescue Exception => e
        msg = "An error occurred getting configuration file for #{category}:\n"+
          "#{e}"
        exc = Exception.new(msg)
        exc.set_backtrace(e.backtrace)
        raise exc
      end
    end
    # for debugging purpose
    attr_reader :'config_cache' 
  end
end

class Hash
  def str_keys_to_sym_keys
    result = self.dup
    str_keys = result.keys.select {|k| k.instance_of? String}
    str_keys.each { |k| result[k.to_sym] = result.delete(k) }
    result
  end
end
